Imports System.Windows.Forms

Public Class frmCalc

    Private NumAdded As Integer = 0
    Private iniSaved As IniFile.clsIniFile = Nothing
    Private BatchMode As Boolean = False

    Private Sub frmCalc_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        SaveControlValues(REGAPP, Me)
        iniSaved.Save()
    End Sub

    Private Sub frmCalc_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Dim dirSaved As String = TestNull(Project.SQLDir, MyDataPath)
            If Not My.Computer.FileSystem.DirectoryExists(dirSaved) Then dirSaved = MyDataPath()
            iniSaved = New IniFile.clsIniFile(IO.Path.Combine(dirSaved, "SavedCalcs.ini"), True)
            Project.FillPickList(cboPCodeIn, clsProject.TempData, "PCodes", "PCode", "Anal_Name", , , String.Format("WHERE Selected_By='{0}'", clsApplicationSettings.UserName))
            Project.FillPickList(cboPCodeIn2, clsProject.TempData, "PCodes", "PCode", "Anal_Name", , , String.Format("WHERE Selected_By='{0}'", clsApplicationSettings.UserName))
            Project.FillPickList(cboPCodeOut, "", "PCodes", "PCode", "Anal_Name", "(Create New)")
            Project.FillPickList(cboCCodeOut, "", "CCodes", "CCode", "CCode_Name", "(Create New)")
            RefreshTableList(cboTableName)
            GetControlValues(REGAPP, Me)
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
        Try
            If txtEquation.Visible And txtEquation.Text.Trim = "" Then
                WarningMsg("You must enter an equation!")
                Exit Sub
            End If

            MainForm.WriteProgress("Opening table")

            Dim PCode As String = Project.GetPickList(cboPCodeOut)
            Dim CCode As String = Project.GetPickList(cboCCodeOut)
            If PCode.StartsWith("(Create") Or CCode.StartsWith("(Create") Then
                WarningMsg("You must select a valid PCode and CCode before continuing.")
                Exit Sub
            End If

            Dim DataTable As clsDataTable

            MainForm.WriteProgress("Retrieving existing data")

            Dim lstExistData As Generic.List(Of clsDataRecord) = Nothing
            Dim dt As DataTable = Nothing

            'assemble all data for first pcode

            DataTable = New clsDataTable(Project, clsProject.TempData)
            lstExistData = DataTable.SelectRecords(String.Format("PCode='{0}' AND Selected_By='{1}'", Project.GetPickList(cboPCodeIn), clsApplicationSettings.UserName), "Date_Time")
            DataTable.Close()

            'if calc two pcodes, assemble dictionary of secondary values; key is stationID & date-time appended
            Dim lstExistData2 As Generic.List(Of clsDataRecord) = Nothing
            If cboCalcType.SelectedIndex = 1 Then
                Dim DataTable2 As New clsDataTable(Project, clsProject.TempData)
                lstExistData2 = DataTable2.SelectRecords(String.Format("PCode='{0}' AND Selected_By='{1}'", Project.GetPickList(cboPCodeIn2), clsApplicationSettings.UserName))
            End If

            Dim TableName As String = cboTableName.Text
            If cboTableName.SelectedIndex = 0 Then TableName = ActiveBrowser.FullTableName

            DataTable = New clsDataTable(Project, TableName)

            MainForm.ProgressComplete()

            Dim NumFound As Integer = DataTable.GetCount("PCode='{0}' AND CCode='{1}'", PCode, CCode)
            Dim RecordsDeletedFirst As Boolean = False

            If BatchMode Then

                MainForm.WriteProgress("Deleting records")
                DataTable.DeleteRecords("PCode='{0}' AND CCode='{1}'", PCode, CCode)

            Else

                If NumFound > 0 Then
                    Select Case frmSelectOption.SelectOption(Me,
                                                             "Calculate New Records",
                                                             StringFormat("WARNING! {0} records were found in the Working table ({3}) that have the specified PCode ({1}) and CCode ({2}). " &
                                                                          "Before computing all values and adding them to the Working table, what do you want to do?",
                                                                          NumFound, PCode.Trim, CCode.Trim, TableName),
                                                             "Use this option for remainder of session",
                                                             "DELETE the existing records and REPLACE them with the new ones",
                                                             "RETAIN the existing records and APPEND the new ones")
                        Case frmSelectOption.enumResult.Button1
                            MainForm.WriteProgress("Deleting records")
                            DataTable.DeleteRecords("PCode='{0}' AND CCode='{1}'", PCode, CCode)
                            RecordsDeletedFirst = True
                        Case frmSelectOption.enumResult.Button2
                            'don't do anything
                        Case frmSelectOption.enumResult.Cancel
                            Exit Sub
                    End Select
                    'Select Case MessageBox.Show(StringFormat("WARNING! {0} records were found in the Working table ({3}) that have the specified PCode ({1}) and CCode ({2}). " &
                    '                                         "Before computing all values and adding them to the Working table, do you want to delete all {0} existing records?\n\n" &
                    '                                         "Click 'Yes' to DELETE the existing records and REPLACE them with the new ones.\n\n" &
                    '                                         "Click 'No' to RETAIN the existing records and APPEND the new ones.\n\n" &
                    '                                         "Click 'Cancel' to abort this operation.",
                    '                                         NumFound, PCode.Trim, CCode.Trim, TableName), "Calculate New Data", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation)
                    '    Case Windows.Forms.DialogResult.Yes
                    '        MainForm.WriteProgress("Deleting records")
                    '        DataTable.DeleteRecords("PCode='{0}' AND CCode='{1}'", PCode, CCode)
                    '    Case Windows.Forms.DialogResult.No
                    '    Case Windows.Forms.DialogResult.Cancel
                    '        Exit Sub
                    'End Select
                End If

            End If

            DataTable.Close()

            Dim ret As Boolean
            Select Case cboCalcType.SelectedIndex
                Case 0 : ret = CalcOnePCode(lstExistData, TableName)
                Case 1 : ret = CalcTwoPCodes(lstExistData, TableName, lstExistData2)
                Case 2 : ret = Calc_Avg_or_Total(lstExistData, TableName)
                Case 3 : ret = Calc_Filter(lstExistData, TableName)
                Case 4 : ret = Calc_Sine(lstExistData, TableName)
            End Select

            If RecordsDeletedFirst Then
                'WarningMsg(String.Format("Note: {0} records with the same PCode and CCode were deleted prior to the addition of the calculated records.", NumFound))
                frmJournal.AddJournalEntry(TableName, frmJournal.enumJournalEntry.Calculate, NumFound, , "Delete before calculate")
            End If

            If ret Then
                Project.UpdateTrackingRecord(TableName, Project.GetRecordCount(TableName), True)
                Project.UpdateOwnerField(TableName)
                frmJournal.AddJournalEntry(TableName, frmJournal.enumJournalEntry.Calculate, NumAdded, , String.Format("Calculate: {0}", cboCalcType.Text))
                MainForm.OpenDataTable(TableName)
                Me.Close()
            End If
        Catch ex As Exception
            ErrorMsg(, ex)
        Finally
            frmJournal.ClearJournalDescription()
            MainForm.ProgressComplete()
        End Try
    End Sub

    Private Function CalcOnePCode(ByRef lstExistData As Generic.List(Of clsDataRecord), ByVal TableName As String) As Boolean
        Dim DataTable As New clsDataTable(Project, TableName)
        DataTable.BeginTransaction()

        Try
            NumAdded = 0
            MainForm.WriteProgress("Calculating new data...", ProgressBarStyle.Marquee)

            For i As Integer = 0 To lstExistData.Count - 1
                With lstExistData(i)
                    .PCode = Project.GetPickList(cboPCodeOut)
                    .CCode = Project.GetPickList(cboCCodeOut)
                    .RCode = ""
                    .Result = txtEquation.Text.Replace("#", .Result)
                    .Result = .Result.Replace(Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".")
                    .Validated = False
                    NumAdded += 1
                    If Not DataTable.InsertRecord(lstExistData(i)) Then
                        WarningMsgFmt("Unable to add record number {0}; the calculation has been aborted.\n\nCheck your equation for validity.", NumAdded)
                        Return False
                    End If
                End With
                MainForm.WriteProgress(i, lstExistData.Count - 1, "Adding records", ProgressBarStyle.Blocks, False)
            Next

            MainForm.ProgressComplete()
            If BatchMode OrElse MessageBox.Show(StringFormat("Do you want to proceed to add a total of {0:N0} records to {1}?", NumAdded, TableName), "Calculate New Data", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) = Windows.Forms.DialogResult.OK Then
                DataTable.Close(clsDataTable.enumEndTransaction.Commit)
                If DataTable.TableName = ActiveTableName() Then clsApplicationSettings.ResetEditTime()
            Else
                DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                Return False
            End If
            Return True
        Catch ex As Exception
            ErrorMsg("Unable to add record; the calculation has been aborted. Check your equation for validity.\n\n", ex)
            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
            Return False
        Finally
            MainForm.ProgressComplete()
        End Try
    End Function

    Private Function CalcTwoPCodes(ByRef lstExistData As Generic.List(Of clsDataRecord), ByVal TableName As String, ByRef lstExistData2 As Generic.List(Of clsDataRecord)) As Boolean
        Dim DataTable As New clsDataTable(Project, TableName)
        DataTable.BeginTransaction()
        Try
            NumAdded = 0
            MainForm.WriteProgress("Calculating new data...", ProgressBarStyle.Marquee)

            Dim dictResults2 As New Generic.Dictionary(Of String, Single)

            For i As Integer = 0 To lstExistData2.Count - 1
                With lstExistData2(i)
                    If Not dictResults2.ContainsKey(.StationID & .DateTime) Then
                        dictResults2.Add(.StationID & .DateTime, .Result)
                    End If
                End With
                MainForm.WriteProgress(i, lstExistData.Count - 1, "Adding records", ProgressBarStyle.Blocks, False)
            Next

            For i As Integer = 0 To lstExistData.Count - 1
                With lstExistData(i)
                    Dim result As Single
                    If dictResults2.TryGetValue(.StationID & .DateTime, result) Then
                        .PCode = Project.GetPickList(cboPCodeOut)
                        .CCode = Project.GetPickList(cboCCodeOut)
                        .RCode = ""
                        .Result = txtEquation.Text.Replace("#", .Result.ToString).Replace("$", result.ToString)
                        .Validated = False
                        Numadded += 1
                        If Not DataTable.InsertRecord(lstExistData(i)) Then
                            WarningMsgFmt("Unable to add record number {0}; the calculation has been aborted.\n\nCheck your equation for validity.", NumAdded)
                            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                            Return False
                        End If
                    End If
                End With
                MainForm.WriteProgress(i, lstExistData.Count - 1, "Adding records", ProgressBarStyle.Blocks, False)
            Next

            MainForm.ProgressComplete()
            If MessageBox.Show(StringFormat("Do you want to proceed to add a total of {0:N0} records to {1}?", Numadded, TableName), "Calculate New Data", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) = Windows.Forms.DialogResult.OK Then
                DataTable.Close(clsDataTable.enumEndTransaction.Commit)
                If DataTable.TableName = ActiveTableName() Then clsApplicationSettings.ResetEditTime()
            Else
                DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                Return False
            End If
            Return True
        Catch ex As Exception
            ErrorMsg(, ex)
            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
            Return False
        Finally
            MainForm.ProgressComplete()
        End Try
    End Function

    Private Function Calc_Avg_or_Total(ByRef lstExistData As Generic.List(Of clsDataRecord), ByVal TableName As String) As Boolean
        Dim DataTable As New clsDataTable(Project, TableName)
        DataTable.BeginTransaction()

        Try
            NumAdded = 0
            Dim Num As Integer = 0
            Dim Sum As Double = 0.0
            Dim NumDaysIncomplete As Integer = 0
            Dim Warnings As String = ""
            Dim LastRecord As clsDataRecord = lstExistData(0)
            Dim RecNum As Integer = 0

            'note: WRDB 4.5 used the USGS method of averaging 25 values--this has been changed to the more logical 24 values

            Dim ConvertDaily As Boolean = cboConvert.SelectedIndex <> 2
            Dim Average As Boolean = cboOperation.SelectedIndex = 0
            MainForm.WriteProgress("Averaging values...")

            Do
                'sum for hour zero through hour zero (24 values if hourly to daily)
                If ConvertDaily Then
                    While RecNum <= lstExistData.Count - 1 AndAlso CDate(lstExistData(RecNum).DateTime).Date = CDate(LastRecord.DateTime).Date 'check Dates
                        Sum += lstExistData(RecNum).Result  'sum Result
                        Num += 1
                        RecNum += 1
                    End While
                Else
                    While RecNum <= lstExistData.Count - 1 AndAlso CDate(lstExistData(RecNum).DateTime).Date = CDate(LastRecord.DateTime).Date AndAlso CDate(lstExistData(RecNum).DateTime).Hour = CDate(LastRecord.DateTime).Hour  'check hours
                        Sum += lstExistData(RecNum).Result  'sum Result
                        Num += 1
                        RecNum += 1
                    End While
                End If

                'add average result to working table, set time to noon if avg daily or end of period if total, and reset pcode and ccode

                'WARNING!!! BECAUSE OF WAY THAT SQLITE STORES DATES IN TABLE, REALLY SHOULD USE PARAMETERS TO STORE DATES IN TABLE; NO PROBLEMS DETECTED HERE THOUGH

                With lstExistData(RecNum - 1)
                    If ConvertDaily Then
                        .DateTime = CDate(.DateTime).Date.AddHours(IIf(Average, 12, 24))
                    Else
                        .DateTime = CDate(.DateTime).Date.AddHours(.DateTime.Hour + IIf(Average, 0.5, 1))
                    End If

                    .PCode = Project.GetPickList(cboPCodeOut)
                    .CCode = Project.GetPickList(cboCCodeOut)
                    .RCode = ""
                    .Result = Math.Round(IIf(Average, Sum / Num, Sum), 3)
                    .Validated = False
                    NumAdded += 1

                    If Not DataTable.InsertRecord(lstExistData(RecNum - 1)) Then
                        WarningMsgFmt("Unable to add record number {0}; the calculation has been aborted.\n\nCheck your equation for validity.", NumAdded)
                        Return False
                    End If

                    If Num <> Choose(cboConvert.SelectedIndex + 1, 24, 24 * 4, 4) Then
                        If NumDaysIncomplete > 20 Then
                            If Not Warnings.Contains("(Too") Then Warnings &= "(Too many to display)"
                        Else
                            If Warnings <> "" Then Warnings &= "; "
                            If ConvertDaily Then
                                Warnings &= String.Format("{0:d} ({1})", .DateTime, Num)
                            Else
                                Warnings &= String.Format("{0} ({1})", CDate(.DateTime).ToString(MyDateTimeFormat), Num)
                            End If
                        End If
                        NumDaysIncomplete += 1
                    End If
                End With

                If RecNum > lstExistData.Count - 1 Then Exit Do

                'reset for next day (pointer is already at hour zero of next day)
                Sum = 0
                Num = 0
                LastRecord = lstExistData(RecNum)

                MainForm.WriteProgress(RecNum - 1, lstExistData.Count - 1, "Adding records", ProgressBarStyle.Blocks, False)
            Loop
            MainForm.ProgressComplete()

            Dim msg As String = StringFormat("{0:N0} records will be added to your currently selected Working table.", NumAdded)
            If NumDaysIncomplete > 0 Then msg &= StringFormat("\n\nNote: {0} {3} ({1:0}% of the total) had other than {4} values from which to compute the {5}. These dates (and the number of available values) were:\n\n{2}", NumDaysIncomplete, NumDaysIncomplete * 100.0 / NumAdded, Warnings, IIf(ConvertDaily, "dates", "hours"), Choose(cboConvert.SelectedIndex + 1, 24, 24 * 4, 4), IIf(Average, "average", "total"))
            msg &= StringFormat("\n\nDo you want to proceed with the operation?")
            If MessageBox.Show(msg, "Calculate New Data", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) = Windows.Forms.DialogResult.OK Then
                DataTable.Close(clsDataTable.enumEndTransaction.Commit)
                If DataTable.TableName = ActiveTableName() Then clsApplicationSettings.ResetEditTime()
            Else
                DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                Return False
            End If
            Return True
        Catch ex As Exception
            ErrorMsg(, ex)
            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
            Return False
        Finally
            DataTable.Close()
            MainForm.ProgressComplete()
        End Try
    End Function

    Private Function Calc_Filter(ByRef lstExistData As Generic.List(Of clsDataRecord), ByVal TableName As String) As Boolean
        Dim DataTable As New clsDataTable(Project, TableName)
        DataTable.BeginTransaction()

        Try
            MainForm.WriteProgress("Filtering values...")

            NumAdded = 0

            Dim threshDev As Single = Val(txtThreshDev.Text)

            Dim Filter As New clsFilter(threshDev)

            For i As Integer = 0 To lstExistData.Count - 1
                With lstExistData(i)
                    .PCode = Project.GetPickList(cboPCodeOut)
                    .CCode = Project.GetPickList(cboCCodeOut)
                    If Filter.FilterValue(.DateTime, .Result) Then
                        If DataTable.InsertRecord(lstExistData(i)) Then
                            NumAdded += 1
                        Else
                            WarningMsgFmt("Unable to add record number {0}; the calculation has been aborted.", NumAdded)
                            Return False
                        End If
                    End If
                    If Not MainForm.WriteProgress(i - 1, lstExistData.Count - 1, "Filtering values...", ProgressBarStyle.Blocks, True) Then Return False
                    If i = lstExistData.Count - 1 Then
                        Filter.LastFilterValue(.DateTime, .Result)
                        DataTable.InsertRecord(lstExistData(i))
                    End If
                End With
            Next
            MainForm.ProgressComplete()

            Dim NumFiltered As Integer = lstExistData.Count - NumAdded
            Dim msg As String = StringFormat("{0:N0} records will be added to your currently selected Working table; {1:N0} records were filtered out ({2:0}%).\n\nDo you want to proceed with the operation?", NumAdded, NumFiltered, NumFiltered * 100.0 / lstExistData.Count)
            If WarningMsg(msg) = Windows.Forms.DialogResult.OK Then
                DataTable.Close(clsDataTable.enumEndTransaction.Commit)
                If DataTable.TableName = ActiveTableName() Then clsApplicationSettings.ResetEditTime()
                MainForm.SelectAll()
                With New WRDB.Graph.clsGraph
                    Dim SQLString As String = FormatSQL(clsApplicationSettings.GetKey(enumKey.LastQuerySQL, ""))
                    .ShowGraph(MainForm, Project.Name, clsProject.TempData, Graph.enumGraphType.TimeSeries, True, SQLString)
                    Dim StationID As String = lstExistData(0).StationID
                    .AddSeries(StationID, Project.GetPickList(cboPCodeIn), True, False)
                    .AddSeries(StationID, Project.GetPickList(cboPCodeOut), False, True, StringFormat("Deviation Threshold: {0}%\n{1:0}% of values filtered out", threshDev, NumFiltered * 100.0 / lstExistData.Count).Replace(vbCr, vbCrLf))
                End With
                Return True
            Else
                DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                Return False
            End If
        Catch ex As Exception
            ErrorMsg(, ex)
            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
            Return False
        Finally
            DataTable.Close()
            MainForm.ProgressComplete()
        End Try
    End Function

    Private Function Calc_Sine(ByRef lstExistData As Generic.List(Of clsDataRecord), ByVal TableName As String) As Boolean
        Dim DataTable As New clsDataTable(Project, TableName)
        DataTable.BeginTransaction()

        Try
            MainForm.WriteProgress("Computing sine curve...")
            'compute the best-fit sine curve
            Dim Date_Time(lstExistData.Count - 1) As Double, Value(lstExistData.Count - 1) As Double
            For i As Integer = 0 To lstExistData.Count - 1
                Date_Time(i) = CDate(lstExistData(i).DateTime).ToOADate
                Value(i) = lstExistData(i).Result
            Next
            Dim Mean, Amplitude, PhaseAngle, StdDev As Double, Description As String = ""
            Dim Period As Double = Choose(cboPeriod.SelectedIndex + 1, 1, 7, 30, 365)
            If Not modNLFit.ComputeSineCurve(Date_Time, Value, Mean, Amplitude, PhaseAngle, Period, StdDev, Description) Then Return False

            'use the exceedance probability to shift series

            Dim TimeStepHours As Integer = IIf(cboPeriod.SelectedIndex = 3, 24, 1)
            Dim MinDate As Date = CDate(lstExistData(0).DateTime).Date
            Dim MaxDate As Date = CDate(lstExistData(lstExistData.Count - 1).DateTime).Date.AddDays(1)
            NumAdded = 0
            Dim z As Double = modProbability.NormalInv(1 - Val(cboPercent.Text) / 100.0)
            Dim Station_ID As String = lstExistData(0).StationID  'use first stationID for all
            Dim Agency As String = TestNull(lstExistData(0).Agency, "")
            Dim PCode As String = Project.GetPickList(cboPCodeOut)
            Dim CCode As String = Project.GetPickList(cboCCodeOut)
            Dim dt As Date = MinDate
            Do While dt <= MaxDate
                Dim Result As Double = Mean + Amplitude * (Math.Sin(2 * Math.PI / Period * dt.ToOADate + PhaseAngle))
                Result += z * StdDev
                Dim dataRecord As New clsDataRecord(Station_ID, dt, PCode, Math.Round(Result, 3), CCode, , , , Agency)
                If Not DataTable.InsertRecord(dataRecord) Then
                    WarningMsgFmt("Unable to add record number {0}; the calculation has been aborted.\n\nCheck your equation for validity.", NumAdded)
                    Return False
                End If
                NumAdded += 1
                dt = dt.AddHours(TimeStepHours)
                If Not MainForm.WriteProgress(dt.Subtract(MinDate).TotalHours, MaxDate.Subtract(MinDate).TotalHours, "Saving computed data to table...", ProgressBarStyle.Continuous, True) Then Return False
            Loop
            If MessageBox.Show(StringFormat("Do you want to proceed to add {0} computed records to {1}?", NumAdded, TableName), "Calculate New Data", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.OK Then
                DataTable.Close(clsDataTable.enumEndTransaction.Commit)
                If DataTable.TableName = ActiveTableName() Then clsApplicationSettings.ResetEditTime()
            Else
                DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
                Return False
            End If
            Return True
        Catch ex As Exception
            ErrorMsg(, ex)
            DataTable.Close(clsDataTable.enumEndTransaction.Rollback)
            Return False
        Finally
            DataTable.Close()
            MainForm.ProgressComplete()
        End Try
    End Function

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub cboCalcType_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboCalcType.SelectedIndexChanged
        Select Case cboCalcType.SelectedIndex
            Case 0
                pnlEquation.Visible = True
                lblPCodeIn2.Visible = False
                cboPCodeIn2.Visible = False
                lblPCodeIn.Text = "&PCode:"
                lblEquation.Text = "&Equation:\n(use # for placeholder; e.g., 0.123 + 4.567 * #)".Replace("\n", vbCrLf)
                pnlAverages.Visible = False
                pnlSine.Visible = False
                pnlFilter.Visible = False
            Case 1
                pnlEquation.Visible = True
                lblPCodeIn2.Visible = True
                cboPCodeIn2.Visible = True
                lblPCodeIn.Text = "&PCode 1:"
                lblEquation.Text = "&Equation:\n(use # and $ for placeholders 1 and 2; e.g., 0.123 * # + 4.567 * $)".Replace("\n", vbCrLf)
                pnlAverages.Visible = False
                pnlSine.Visible = False
                pnlFilter.Visible = False
            Case 2
                lblPCodeIn2.Visible = False
                cboPCodeIn2.Visible = False
                pnlEquation.Visible = False
                pnlAverages.Visible = True
                pnlSine.Visible = False
                pnlFilter.Visible = False
            Case 3
                lblPCodeIn2.Visible = False
                cboPCodeIn2.Visible = False
                pnlEquation.Visible = False
                pnlAverages.Visible = False
                pnlSine.Visible = False
                pnlFilter.Visible = True
            Case 4
                lblPCodeIn2.Visible = False
                cboPCodeIn2.Visible = False
                pnlEquation.Visible = False
                pnlAverages.Visible = False
                pnlSine.Visible = True
                pnlFilter.Visible = False
        End Select
    End Sub

    Private Sub btnHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHelp.Click
        ShowHelp(Me, "5")
    End Sub

    Shared Sub RefreshTableList(ByRef cbo As ComboBox)
        With cbo.Items
            .Clear()
            If ActiveTableType() = clsProject.enumTableTypes.Working Then .Add("(Current Table)")
            .Add("(New Table)")
            .AddRange(Project.GetTableList.ToArray)
        End With
    End Sub

    Shared Sub TableSelectionCommitted(ByRef cbo As ComboBox)
        With cbo
            If .Text = "(New Table)" Then
                Dim TableName As String = MainForm.FileNewWorking(False)
                If TableName = "" Then
                    .SelectedIndex = 0
                Else
                    frmCalc.RefreshTableList(cbo)
                    .Text = TableName
                End If
            End If
        End With
    End Sub

    Private Sub cboTableName_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboTableName.SelectionChangeCommitted
        TableSelectionCommitted(cboTableName)
    End Sub

    Shared Sub PCodeSelectionCommitted(ByRef cbo As ComboBox)
        With cbo
            If .Text = "(Create New)" Then
                Dim PCode As String = InputBox("Enter the new PCode you wish to add (later you can edit the Support table to add the analysis name and other fields):", "Create New PCode").ToUpper
                If PCode = "" Then
                    .SelectedIndex = 0
                Else
                    If PCode.Length > 10 Then
                        WarningMsg("The PCode must be no more than 10 characters.")
                    ElseIf Project.DB.GetRecordList("PCodes", "PCode").Contains(PCode) Then
                        WarningMsg("The PCode you entered already exists.")
                    Else
                        Project.DB.ExecuteNonQuery($"INSERT INTO {Project.FullTableName(clsProject.enumTableTypes.PCodes)} (PCode) VALUES ('{PCode}')")
                        Project.DB.UpdateRecordTimeStamp("PCodes", String.Format("WHERE PCode='{0}'", PCode))
                        Project.FillPickList(cbo, "", "PCodes", "PCode", "Anal_Name", "(Create New)", PCode)
                    End If
                End If
            End If
        End With
    End Sub

    Private Sub cboPCodeOut_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboPCodeOut.SelectionChangeCommitted
        PCodeSelectionCommitted(cboPCodeOut)
    End Sub

    Shared Sub CCodeSelectionCommitted(ByRef cbo As ComboBox)
        With cbo
            If .Text = "(Create New)" Then
                Dim CCode As String = InputBox("Enter the new CCode you wish to add (later you can edit the Support table to add the CCode name and description):", "Create New CCode").ToUpper
                If CCode = "" Then
                    .SelectedIndex = 0
                Else
                    If CCode.Length > 3 Then
                        WarningMsg("The CCode must be no more than 3 characters.")
                    ElseIf Project.DB.GetRecordList("CCodes", "CCode").Contains(CCode) Then
                        WarningMsg("The CCode you entered already exists.")
                    Else
                        Project.DB.ExecuteNonQuery($"INSERT INTO {Project.FullTableName(clsProject.enumTableTypes.CCodes)} (CCode) VALUES ('{CCode}')")
                        Project.FillPickList(cbo, "", "CCodes", "CCode", "CCode_Name", "(Create New)", CCode)
                    End If
                End If
            End If
        End With
    End Sub

    Private Sub cboCCodeOut_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboCCodeOut.SelectionChangeCommitted
        CCodeSelectionCommitted(cboCCodeOut)
    End Sub

    Private Sub btnJournal_Click(sender As System.Object, e As System.EventArgs) Handles btnJournal.Click
        frmJournal.GetJournalDescription()
    End Sub

    Private Sub btnSaved_Click(sender As System.Object, e As System.EventArgs) Handles btnSaved.Click
        mnuSaved.Show(btnSaved, btnSaved.Width / 2, btnSaved.Height / 2)
    End Sub

    Private Sub mnuSaved_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles mnuSaved.Opening
        For i As Integer = mnuSaved.Items.Count - 1 To 5 Step -1
            mnuSaved.Items.RemoveAt(i)
        Next
        iniSaved.Sort()
        For Each s As String In iniSaved.GetSectionNames
            mnuSaved.Items.Add(s)
        Next
    End Sub

    Private Sub mnuCalcSave_Click(sender As Object, e As System.EventArgs) Handles mnuCalcSave.Click
        Dim SectionName As String = InputBox("Enter the name to be assigned to this saved calculation defined by the inputs currently on the form:", "Save New Calculation")
        If SectionName = "" Then Exit Sub
        If iniSaved.GetSectionNames.Contains(SectionName) AndAlso WarningMsg("A calculation with this name already exists; do you want to overwrite its definition?", , , , "Save Calculation") = Windows.Forms.DialogResult.Cancel Then Exit Sub

        With cboCalcType : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboPCodeIn : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboPCodeIn2 : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With txtEquation : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboPeriod : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboPercent : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboPCodeOut : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboCCodeOut : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
        With cboTableName : iniSaved.SetKeyText(SectionName, .Name, .Text) : End With
    End Sub

    Private Sub mnuCalcDelete_Click(sender As Object, e As System.EventArgs) Handles mnuCalcDelete.Click
        With New frmList
            .ListBox1.Items.AddRange(iniSaved.GetSectionNames.ToArray)
            .ListBox1.SelectionMode = SelectionMode.MultiSimple
            If .ShowDialog = Windows.Forms.DialogResult.OK Then
                For Each s As String In .ListBox1.SelectedItems
                    iniSaved.DeleteSection(s)
                Next
            End If
        End With
    End Sub

    Private Sub mnuCalcAll_Click(sender As Object, e As System.EventArgs) Handles mnuCalcAll.Click
        Try

            If WarningMsg("This will perform all calculations as a single batch operation. Please note that all existing records in the output Working table(s) that have the specified PCodes and CCodes will be deleted first to prevent duplicates from being created.\n\nDo you want to continue?", , , , "Calculate All") = Windows.Forms.DialogResult.Cancel Then Exit Sub
            For Each s As String In iniSaved.GetSectionNames
                Restore(s)
                BatchMode = True
                btnCalc.PerformClick()
            Next


        Catch ex As Exception

            ErrorMsg(, ex)

        Finally

            BatchMode = False

        End Try

    End Sub

    Private Sub mnuSaved_ItemClicked(sender As Object, e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles mnuSaved.ItemClicked
        If mnuSaved.Items.IndexOf(e.ClickedItem) >= 5 Then
            Restore(e.ClickedItem.Text)
        End If
    End Sub

    Private Sub Restore(SectionName As String)
        With cboCalcType : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboPCodeIn : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboPCodeIn2 : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With txtEquation : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboPeriod : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboPercent : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboPCodeOut : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboCCodeOut : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
        With cboTableName : .Text = iniSaved.GetKeyText(SectionName, .Name, "") : End With
    End Sub

    Private Sub txt_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtEquation.KeyPress, txtThreshDev.KeyPress
        If e.KeyChar = "." Then
            e.KeyChar = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
        End If
    End Sub
End Class
